package com.alks.function.service.impl.stockdept.pcfactorystockquery;

import com.alks.common.aop.AutoPageAop;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.service.RedisService;
import com.alks.common.utils.beanutils.ArrayUtils;
import com.alks.common.utils.beanutils.BeanUtil;
import com.alks.entity.data.entity.PcMtlAcc;
import com.alks.entity.data.entity.PcSurplusDetail;
import com.alks.entity.data.entity.PcSurplusTemp;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.function.data.dto.stockdept.pcfactorystockwork.LotMtlDto;
import com.alks.function.data.dto.stockdept.pcfactorystockwork.SurpDetailDto;
import com.alks.function.data.dto.stockdept.pcfactorystockwork.SurplusTempDto;
import com.alks.function.data.request.stockdept.pcfactorystockwork.LotMtlRequest;
import com.alks.function.data.request.stockdept.pcfactorystockwork.OMtlWatiUpRequest;
import com.alks.function.data.request.stockdept.pcfactorystockwork.OMtlwaitAddRequest;
import com.alks.function.data.request.stockdept.pcfactorystockwork.SurpDetailRequest;
import com.alks.function.mapper.stockdept.pcfactorystockquery.SD_SQ_PcLotUsageMapper;
import com.alks.function.mapper.stockdept.pcfactorystockquery.SD_SQ_PcMtlAccMapper;
import com.alks.function.mapper.stockdept.pcfactorystockquery.SD_SQ_PcSurplusDetailMapper;
import com.alks.function.mapper.stockdept.pcfactorystockquery.SD_SQ_PcSurplusTempMapper;
import com.alks.function.service.stockdept.pcfactorystockquery.IPcSurplusService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.alks.entity.data.enums.ResultCodeEnum.*;

@Service
@Slf4j
@RequiredArgsConstructor
public class PcSurplusServiceImpl extends ServiceImpl<SD_SQ_PcSurplusDetailMapper, PcSurplusDetail> implements IPcSurplusService {
    private final SD_SQ_PcSurplusTempMapper tempMapper;
    private final SD_SQ_PcLotUsageMapper usageMapper;
    private final SD_SQ_PcSurplusDetailMapper detailMapper;
    private final SD_SQ_PcMtlAccMapper accMapper;
    private final SD_SQ_PcLotUsageMapper lotMapper;
    private final RedisService redisService;

    @Override
    public ResponseInfo getSurpTempQuery() {
        /*获取数据*/
        List<SurplusTempDto> dtos = tempMapper.getSurpTempQuery(UserIdThread.get().getUserName());
        return ResponseInfo.ok(dtos);
    }

    @Override
    public ResponseInfo surpTempAdd(List<OMtlwaitAddRequest> request) {
        /*判断入参是否重复*/
        if (request == null || request.isEmpty()) {
            return ResponseInfo.error("请选择入库材料", IN_IS_EMPTY.getCode());
        }
        String companyId = UserIdThread.get().getCompanyId();
        List<String> mtls = request.stream().map(OMtlwaitAddRequest::getMtlNo).collect(Collectors.toList());
        LambdaQueryWrapper<PcSurplusTemp> tempWrapper = new LambdaQueryWrapper<PcSurplusTemp>()
                .select(PcSurplusTemp::getMtlNo)
                .eq(PcSurplusTemp::getCompanyId,companyId)
                .eq(PcSurplusTemp::getSysUser,UserIdThread.get().getUserName())
                .eq(PcSurplusTemp::getSlipType,"I")
                .in(PcSurplusTemp::getMtlNo, mtls);
        List<String> ReMtlNos = tempMapper.selectList(tempWrapper).stream().map(PcSurplusTemp::getMtlNo).collect(Collectors.toList());
        if (!ArrayUtils.isEmpyt(ReMtlNos)) {
            log.warn("异常接口：surpTempAdd\n异常原因：试图添加重复物料{}",ReMtlNos);
            return ResponseInfo.error("存在重复物料"+ReMtlNos, DATA_IS_ERR.getCode());
        }
        /*判断材料是否建档*/
        LambdaQueryWrapper<PcMtlAcc> accWrapper = new LambdaQueryWrapper<PcMtlAcc>()
                .eq(PcMtlAcc::getCompanyId,companyId)
                .in(PcMtlAcc::getMtlNo,mtls);
        List<PcMtlAcc> mtlAccs = accMapper.selectList(accWrapper);
        List<String> accMtlNos = mtlAccs.stream().map(PcMtlAcc::getMtlNo).collect(Collectors.toList());
        if (!accMtlNos.containsAll(mtls)) {
            log.warn("异常接口：surpTempAdd\n异常原因：试图添加未建档的物料{}",mtls);
            return ResponseInfo.error("存在未建档的物料"+mtls, DATA_IS_ERR.getCode());
        }
        /*获取要写入的数据*/
        List<PcSurplusTemp> temps = BeanUtil.copyList(mtlAccs, PcSurplusTemp.class);
        if (!BeanUtil.allIsEmpty(request.get(0).getLotNo())) {
            Map<String, String> lotMtls = request.stream()
                    .collect(Collectors.toMap(OMtlwaitAddRequest::getLotNo, OMtlwaitAddRequest::getMtlNo));
            List<Map<String, Object>> lots = lotMapper.getQtyByMap(lotMtls,companyId);
            Map<String, BigDecimal> lotQty = lots.stream()
                    .collect(Collectors.toMap(a -> (String)a.get("mtlNo"), a -> (BigDecimal)a.get("qty")));
            /*写入数量*/
            for (PcSurplusTemp temp : temps) {
                temp.setQty(lotQty.get(temp.getMtlNo()).floatValue());
            }
        }
        /*写入补充数据*/
        LambdaQueryWrapper<PcSurplusTemp> tempWrapper1 = new LambdaQueryWrapper<PcSurplusTemp>()
                .select(PcSurplusTemp::getMtlNo)
                .eq(PcSurplusTemp::getCompanyId,companyId)
                .eq(PcSurplusTemp::getSysUser,UserIdThread.get().getUserName())
                .eq(PcSurplusTemp::getSlipType,"I");
        int item = tempMapper.selectList(tempWrapper1).stream()
                .filter(Objects::nonNull)
                .mapToInt(PcSurplusTemp::getItem)
                .max().orElse(0);
        for (PcSurplusTemp temp : temps) {
            item++;
            temp.setItem(item);
            temp.setSysUser(UserIdThread.get().getUserName());
            temp.setSysDate(LocalDateTime.now());
            temp.setSlipType("I");
            temp.setStockNo("XS");
            tempMapper.insert(temp);
        }
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo surpTempUpdate(List<OMtlWatiUpRequest> request) {
        /*更新数据*/
        tempMapper.surpTempUpdate(request,UserIdThread.get().getUserName());
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo surpTempDelete(String mtlNo) {
        /*删除数据*/
        LambdaQueryWrapper<PcSurplusTemp> wrapper = new LambdaQueryWrapper<PcSurplusTemp>()
                .eq(PcSurplusTemp::getMtlNo, mtlNo)
                .eq(PcSurplusTemp::getSlipType,"I")
                .eq(PcSurplusTemp::getSysUser,UserIdThread.get().getLoginName())
                .last("LIMIT 1");
        tempMapper.delete(wrapper);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo getSurpDetailQuery(SurpDetailRequest request) {
        /*获取数据*/
        List<PcSurplusDetail> details = lambdaQuery()
                .eq(request.getSlipNo() != null && !request.getSlipNo().isEmpty(), PcSurplusDetail::getSlipNo, request.getSlipNo())
                .eq(request.getSlipReason() != null && !request.getSlipReason().isEmpty(), PcSurplusDetail::getSlipReason, request.getSlipReason())
                .ge(request.getSlipDateStart() != null, PcSurplusDetail::getSlipDate, request.getSlipDateStart())
                .le(request.getSlipDateEnd() != null, PcSurplusDetail::getSlipDate, request.getSlipDateEnd())
                .ne(request.getType() != null && request.getType() == 2, PcSurplusDetail::getCfmFlag, "Y")
                .eq(request.getType() != null && request.getType() == 3, PcSurplusDetail::getCfmFlag, "Y")
                .eq(PcSurplusDetail::getSysUser, UserIdThread.get().getUserName()).list();
        /*抽取数据*/
        List<SurpDetailDto> dtos = BeanUtil.copyList(details, SurpDetailDto.class);
        return ResponseInfo.ok(dtos);
    }

    @Override
    public ResponseInfo surpDetailAdd(String mtlNo, String slipReason) {
        /*获取数据*/
        LambdaQueryWrapper<PcSurplusTemp> wrapper = new LambdaQueryWrapper<PcSurplusTemp>()
                .select(PcSurplusTemp::getCompanyId, PcSurplusTemp::getMtlName, PcSurplusTemp::getMtlColor, PcSurplusTemp::getMtlName,
                        PcSurplusTemp::getMtlUnit, PcSurplusTemp::getMtlSpec, PcSurplusTemp::getQty, PcSurplusTemp::getLotNo,
                        PcSurplusTemp::getRemark, PcSurplusTemp::getItem, PcSurplusTemp::getSlipType,PcSurplusTemp::getMtlNo)
                .eq(PcSurplusTemp::getMtlNo, mtlNo)
                .last("LIMIT 1");
        PcSurplusTemp temps = tempMapper.selectOne(wrapper);
        if (temps==null||temps.getQty() == null || temps.getQty() == 0) {
            return ResponseInfo.error("请输入入库数量", INPUT_ERROR.getCode());
        }
        /*写入其他数据*/
        PcSurplusDetail detail = BeanUtil.copyBean(temps, PcSurplusDetail.class);
        String slipNo = redisService.slipNoCreat("E");
        detail.setSlipNo(slipNo);
        detail.setStockNo("XS");
        detail.setSlipReason(slipReason);
        detail.setSlipDate(LocalDateTime.now());
        detail.setSysDate(LocalDateTime.now());
        detail.setSysUser(UserIdThread.get().getUserName());
        detail.setSysUser(UserIdThread.get().getUserName());
        /*新增数据*/
        detailMapper.insert(detail);
        /*删除待入数据*/
        LambdaQueryWrapper<PcSurplusTemp> tempWrapper = new LambdaQueryWrapper<PcSurplusTemp>()
                .eq(PcSurplusTemp::getMtlNo, mtlNo)
                .eq(PcSurplusTemp::getSysUser, UserIdThread.get().getUserName());
        tempMapper.delete(tempWrapper);
        return ResponseInfo.ok("入库成功,单号为：" + slipNo);
    }

    @Override
    public ResponseInfo surpDetailDelete(String mtlNo, String slipNo) {
        /*删除数据*/
        LambdaQueryWrapper<PcSurplusDetail> wrapper = new LambdaQueryWrapper<PcSurplusDetail>()
                .eq(PcSurplusDetail::getSlipNo, slipNo)
                .eq(PcSurplusDetail::getMtlNo, mtlNo)
                .eq(PcSurplusDetail::getSlipType,"I")
                .eq(PcSurplusDetail::getSysUser,UserIdThread.get().getLoginName())
                .last("LIMIT 1");
        detailMapper.delete(wrapper);
        return ResponseInfo.ok();
    }

    @Override
    @AutoPageAop
    public ResponseInfo getLotMtlQuery(LotMtlRequest request, int slipType) {
        /*获取数据*/
        List<LotMtlDto> dtos = usageMapper.getLotMtlQuery1(request,slipType);
        Page<LotMtlDto> page = (Page<LotMtlDto>) dtos;
        /*封装数据*/
        Map<String,Object> map = new HashMap<>();
        map.put("total", page.getTotal());
        map.put("dtos", dtos);
        return ResponseInfo.ok(map);
    }
}
